package com.ws.shop.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Repository;

import com.ws.shop.dao.AuctionDao;
import com.ws.shop.dao.AuctionLogDao;
import com.ws.shop.dao.CommonDao;
import com.ws.shop.dao.MemberDao;
import com.ws.shop.entity.Article;
import com.ws.shop.entity.Auction;
import com.ws.shop.entity.AuctionLog;
import com.ws.shop.entity.Member;
import com.ws.shop.entity.Sunpic;
import com.ws.shop.service.AuctionCache;

/**
 * 
 * 缓存提供
 * @author Administrator
 *
 */
@Repository(value="auctionCache")
public class AuctionCacheImpl implements AuctionCache,InitializingBean{
	
	private static Logger log = Logger.getLogger(AuctionCacheImpl.class);
	
	@Resource(name="auctionDao")
	private  AuctionDao auctionDao;
	
	@Resource(name="auctionlogDao")
	private AuctionLogDao auctionlogDao;
	
	@Resource(name="memberDao")
	private MemberDao memberDao;
	
	@Resource(name="commonDao")
	private CommonDao commonDao;
	
	@Resource
	private TaskExecutor taskExecutor;
	
	private static String synlock = "indexlock";
	
	//缓存正在竞拍的所有数据
	public static Map<Long,Auction> auctionCache = new HashMap<Long,Auction>(); 
	public static Map<Long,Auction> camap = new HashMap<Long,Auction>();
	//缓存正在竞拍的日志数据
	//public static List<AuctionLog> auctionlogCache = new LinkedList<AuctionLog>();
	//缓存机器人用户数据
	public static Map<Long,List<Member>> memberCache = new HashMap<Long,List<Member>>();
	
	//存放正在竞拍的日志，每个竞拍的日志
	public static Map<Long,List<AuctionLog>> auctionLogCaches = new HashMap<Long,List<AuctionLog>>();
	//查询所有机器人
	public static List<Member> robotCache = new LinkedList<Member>();
	
	public static List<Auction> auctionlist = new LinkedList<Auction>();
	public static List<Auction> auctedlist = new  LinkedList<Auction>();
	public static List<Article> articlelist = new LinkedList<Article>();
	public static List<Sunpic> sunpiclist = new LinkedList<Sunpic>();
	public void checkCache(long updatetime){
		try {
			taskExecutor.execute(new Runnable() {
				public void run(){
					while(true){
						try {
							System.out.println("++++++++++++++ checkCache ++++++++++++++++++");
							Map<String,List> maplist = commonDao.loadCmmonInfo();
							List<Auction> list = maplist.get("auctioning");
							setAuctioning(list);
							List<Auction> edlist = maplist.get("auctioned");
							setAuctioned(edlist);
							List<Article> articles = maplist.get("article");
							setArticle(articles);
							List<Sunpic> sunpics = maplist.get("sunpic");
							setSunpics(sunpics);
							camap.clear();
							setAuctionCache();
							clearAuctioned();
							Thread.currentThread().sleep(10*1000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						} catch (Exception ex){
							ex.printStackTrace();
						}
					}
				}
			});
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("+++++++++++++checkCache++++++++++++",e);
		}
	}
	
	public static void setAuctioning(List<Auction> list){
		synchronized(synlock){
			if(list.size()>0){				
				auctionlist = list;
				for(int i=0;i<list.size();i++){
					Auction auc = list.get(i);
					long aid = auc.getId();
					if(!auctionCache.containsKey(aid)){
						auctionCache.put(aid, auc);
					}
				}
			}
		}
	}
	
	//清理已经被竞拍的
	public static void clearAuctioned(){
		Set<Long> set = auctionCache.keySet();
		Iterator<Long> it = set.iterator();
		while(it.hasNext()){
			long key = it.next(); //十分钟没有访问的竞拍结束的，我们删除
			Auction auction = auctionCache.get(key);
			if(auction.getState() == 2 && (new Date().getTime() - auction.getRequsttime()) > 60*10*1000){
				it.remove();
			}
		}
	}
	
	public static void setAuctionCache(){
		for(int i=0;i<auctionlist.size();i++){
			camap.put(auctionlist.get(i).getId(), auctionlist.get(i));
		}
	}
	
	public static void setAuctioned(List<Auction> list){
		synchronized(synlock){
			if(list.size()>0){				
				auctedlist = list;
			}
		}
	}
	public static void setArticle(List<Article> articles){
		synchronized(synlock){
			if(articles.size()>0){				
				articlelist = articles;
			}
		}
	}
	public static void setSunpics(List<Sunpic> list){
		synchronized(synlock){
			if(list.size()>0){				
				sunpiclist = list;
			}
		}
	}
	 
	
	public void reload(){
		log.info("+++++++ start load auctioning data +++++++");
		int state = 1; //正在竞拍
		Map<Long,Auction> auctionMap = auctionDao.getAuctionByState(state);
		if(auctionMap != null || auctionMap.size() > 0){
			auctionCache = auctionMap;
		}
		log.info("++++++++ load auctioning complie++++++");
		log.info("++++++++ start load auctioning log ++++++");
		//正在竞拍的日志（10条）
		for(int i=0;i<auctionCache.size();i++){
			Iterator<Long> iter = auctionCache.keySet().iterator();
			while(iter.hasNext()){
				long aid = iter.next();
				log.info("+++++++++ " + aid);
				List<AuctionLog> loglist = auctionlogDao.getLogData(aid);
				auctionLogCaches.put(aid, loglist);
				List<Member> robots = memberDao.getRobotByAuctionId(aid);
				memberCache.put(aid, robots);
			}
		}
		log.info("++++++++ load auctioning log complie++++++");
		log.info("++++++++ start load all robots ++++++ ");
		int robot = 1;
		List<Member> robots = memberDao.getAllRobots(robot);
		if(robots != null && robots.size()>0){			
			robotCache = robots;
		}
		log.info("++++++++ load  robots complie++++++");
		checkCache(0);
	}
	
	public static synchronized Auction getAuctionFromCache(long id){
		return auctionCache.get(id);
	}
	
	public static synchronized void setAuctionToCache(Auction auction){
		auctionCache.put(auction.getId(), auction);
	}
	
	public static synchronized void setAuctionLogToCache(AuctionLog auctionlog){
		List<AuctionLog> aloglist = auctionLogCaches.get(auctionlog.getAid());
		if(aloglist!=null){
			if(aloglist.size()>=10){
				aloglist.remove(0);
				aloglist.add(auctionlog);
			}
		}else{
			List<AuctionLog> aloglinked = new LinkedList<AuctionLog>();
			aloglinked.add(auctionlog);
			auctionLogCaches.put(auctionlog.getAid(), aloglinked);
		}
	}
	
	public static synchronized void handlerstate(){
		Iterator<Long> its = auctionCache.keySet().iterator();
		while(its.hasNext()){
			long key = its.next();
			Auction auction = auctionCache.get(key);
			if(auction.getState() == 1 && auction.getEndtime().compareTo(new Date()) <= 0){
				int state = 0;
				log.info("++++++ update state  is 2 +++++++");
				int updateState = updateState(auction.getId(),state);
				if(updateState>0){					
					auction.setState(2);
				}
			}
		}
	}
	
	public static  int updateState(long id,int state){
		//return auctionDao.updateState(id, state);
		return 0;
	}
	
	public static synchronized List<AuctionLog> getAuctionLogFromCache(long aid){
		return auctionLogCaches.get(aid);
	}
	
	public static synchronized List<Member> getRobotFromCache(long aid){
		return memberCache.get(aid);
	}
	
	public static synchronized void removeAll(long aid){
		auctionCache.remove(aid);
		auctionLogCaches.remove(aid);
		memberCache.remove(aid);
	}
	
	public void afterPropertiesSet() throws Exception {
		reload();
	}

	
}
